package com.qkl.user.service;

import com.qkl.user.dto.ExceptionResponse;
import com.qkl.user.dto.JwtResponse;
import com.qkl.user.dto.LoginRequest;
import com.qkl.user.dto.RegisterRequest;
import com.qkl.user.entity.*;
import com.qkl.user.enums.ExceptionEnum;
import com.qkl.user.exception.OperationException;
import com.qkl.user.mapper.*;
import com.qkl.user.utils.JwtUtils;

import com.qkl.user.utils.RedisCaptchaUtil;
import com.qkl.user.utils.UniqueRandomUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
public class AuthService {



    @Autowired
    private UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;
    private final AuthenticationManager authenticationManager;

    @Autowired
    private UserProblemMapper userProblemMapper;
    @Autowired
    private ProblemMapper problemMapper;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private InvitationRelationMapper invitationRelationMapper;
    @Autowired
    private MatrixService matrixService;
    @Autowired
    private RedisCaptchaUtil redisCaptchaUtil;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserLevelMapper userLevelMapper;
    // 用户登录（生成JWT令牌）
    public JwtResponse login(LoginRequest request) {
        // 验证码
        String storedCode = redisCaptchaUtil.getCaptcha(request.getCaptchaKey());
        log.info("storedCode:{}", storedCode);
        // 3. 校验逻辑（忽略大小写，一次性有效）
        if (storedCode != null && storedCode.equals(request.getCaptcha().trim().toLowerCase())) {
            redisCaptchaUtil.deleteCaptcha(request.getCaptchaKey()); // 校验成功后删除，防止重复使用
        } else {
            throw new OperationException(ExceptionEnum.CAPTCHA_INVALID);
        }
        // 认证用户名密码
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        request.getUsername(),
                        request.getPassword()
                )
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = jwtUtils.generateJwtToken(authentication);
        User user = userMapper.getUserByUsername(request.getUsername());
        // 简化：不返回角色
        return new JwtResponse(
                jwt,
                "Bearer",
                user.getId(),
                user.getUsername(),
                user.getInviteCode()
        );
    }

    // 用户注册
    @Transactional
    public void register(RegisterRequest request) {

// 验证码
//        String storedCode = redisCaptchaUtil.getCaptcha(request.getCaptchaKey());
//        // 3. 校验逻辑（忽略大小写，一次性有效）
//        if (storedCode != null && storedCode.equals(request.getCaptcha().trim().toLowerCase())) {
//            redisCaptchaUtil.deleteCaptcha(request.getCaptchaKey()); // 校验成功后删除，防止重复使用
//        } else {
//            throw new OperationException(ExceptionEnum.CAPTCHA_INVALID);
//        }
        User user = userMapper.getUserByUsername(request.getUsername());
        if (user != null) {
            throw new OperationException(ExceptionEnum.USERNAME_ALREADY_EXISTS);
        }
        if(!request.getTradPassword().equals(request.getTradPasswordTo())){
            throw new OperationException(ExceptionEnum.TRADPASSWORD_AND_TRADPASSWORD);
        }
        //问题
        if(request.getQuestionOne().equals(request.getQuestionTwo())){
            throw new OperationException(ExceptionEnum.SAME_PROBLEM);
        }
        Problem problem1 = problemMapper.selectById(request.getQuestionOne());
        if(problem1 == null){
            throw new OperationException(ExceptionEnum.PROBLEM_ONE_EXITS);
        }
        Problem problem2 = problemMapper.selectById(request.getQuestionTwo());
        if(problem2 == null){
            throw new OperationException(ExceptionEnum.PROBLEM_TWO_EXITS);
        }
        User userNew = new User();
        // 创建新用户
        userNew.setPassword(passwordEncoder.encode(request.getPassword()));
        userNew.setTradPassword(passwordEncoder.encode(request.getTradPassword()));
        userNew.setUsername(request.getUsername());
        userNew.setInviteCode(UniqueRandomUtils.generateRandomNumber(10,"InviteCode"));
        userMapper.insert(userNew);
        UserProblem userProblem = new UserProblem();
        userProblem.setUserId(userNew.getId());
        userProblem.setProblemOneId(request.getQuestionOne());
        userProblem.setProblemTwoId(request.getQuestionTwo());
        userProblem.setAnswerOne(request.getAnswerOne());
        userProblem.setAnswerTwo(request.getAnswerTwo());
        userProblemMapper.insert(userProblem);
        //邀请
        User inviter = userMapper.findUserByInviteCode(request.getInviteCode());
        if(inviter == null){
            throw new OperationException(ExceptionEnum.INVITE_NOT_FOUND);
        }
        Long inviterId = inviter.getId();
        Long newUserId = userNew.getId();
        UserLevel userLevel = new UserLevel();
        userLevel.setUserId(newUserId);
        userLevel.setLevel(0);
        userLevelMapper.insert(userLevel);
        String newUserName = userNew.getUsername();
        // 3. 记录邀请关系
        InvitationRelation invite = new InvitationRelation();
        invite.setUserId(newUserId);
        invite.setInviterId(inviterId);
        invitationRelationMapper.insert(invite);
        // 4. 分配公排位置
        matrixService.assignMatrixPosition(newUserId, inviterId,newUserName);
        String cacheKey = "talent_level:" + inviterId;
        stringRedisTemplate.delete(cacheKey);
    }

}
